﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace DebIt.Common.Model
{
    public class Client : DbStoredItem
    {
        #region variables

        private string _lastName = "";
        private string _firstName = "";
        private string _phonenumber = "";
        private string _eMailAddress = "";
        private decimal _loanSum;
        private readonly ObservableCollection<ClientLoanState> _clientLoanState = new ObservableCollection<ClientLoanState>();

        #endregion


        #region constructor

        public Client()
        {
            _clientLoanState.CollectionChanged += ClientLoanStateCollectionChanged;
            foreach (var cls in _clientLoanState)
            {
                cls.Loan.PropertyChanged += LoanPropertyChanged;
                cls.PropertyChanged += LoanPropertyChanged;
            }
        }

        ~Client()
        {
            _clientLoanState.CollectionChanged -= ClientLoanStateCollectionChanged;
            foreach (var cls in ClientLoanStates)
            {
                cls.Loan.PropertyChanged -= LoanPropertyChanged;
                cls.PropertyChanged -= LoanPropertyChanged;
            }
        }

        #endregion


        #region properties

        public int ClientId { get; set; }

        public string LastName
        {
            get { return _lastName; }
            set
            {
                if (_lastName == value) return;
                SendPropertyChanging(() => LastName);
                _lastName = value;
                SendPropertyChanged(() => LastName);
            }
        }

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                if (_firstName == value) return;
                SendPropertyChanging(() => FirstName);
                _firstName = value;
                SendPropertyChanged(() => FirstName);
            }
        }

        public string Phonenumber
        {
            get { return _phonenumber; }
            set
            {
                if (_phonenumber == value) return;
                SendPropertyChanging(() => Phonenumber);
                _phonenumber = value;
                SendPropertyChanged(() => Phonenumber);
            }
        }

        public string EMailAddress
        {
            get { return _eMailAddress; }
            set
            {
                if (_eMailAddress == value) return;
                SendPropertyChanging(() => EMailAddress);
                _eMailAddress = value;
                SendPropertyChanged(() => EMailAddress);
            }
        }

        public decimal LoanSum
        {
            get { return _loanSum; }
            set
            {
                if (_loanSum == value) return;
                SendPropertyChanging(() => LoanSum);
                _loanSum = value;
                SendPropertyChanged(() => LoanSum);
            }
        }

        public ObservableCollection<ClientLoanState> ClientLoanStates
        {
            get { return _clientLoanState; }
        }

        #endregion


        #region method

        private void CalculateLoanSum()
        {
            var loanSum = ClientLoanStates.Where(x => !x.IsPaid).Aggregate(0m, (x, y) => x + y.Loan.LoanPerClient);
            LoanSum = Math.Round(loanSum, 2);
        }

        public void Add(ClientLoanState clientLoanState)
        {
            _clientLoanState.Add(clientLoanState);
            clientLoanState.Loan.PropertyChanged += LoanPropertyChanged;
            clientLoanState.PropertyChanged += LoanPropertyChanged;
        }

        public void Add(List<ClientLoanState> clientLoanStates)
        {
            clientLoanStates.ForEach(Add);
        }

        public List<ClientLoanState> GetAllLoanItems()
        {
            return ClientLoanStates.ToList();
        }

        public bool Remove(ClientLoanState clientLoanState)
        {
            clientLoanState.Loan.PropertyChanged -= LoanPropertyChanged;
            clientLoanState.PropertyChanged -= LoanPropertyChanged;
            return ClientLoanStates.Remove(clientLoanState);
        }

        void ClientLoanStateCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            CalculateLoanSum();
        }

        void LoanPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName.Equals("LoanPerClient") || e.PropertyName.Equals("IsPaid"))
                CalculateLoanSum();
        }

        #endregion

    }
}
